package com.ma.a03;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName TestMethodTemplate
 * @Author: mayongqiang
 * @DATE 2022/3/30 22:50
 * @Description: 模板方法设计模式
 */

public class TestMethodTemplate {
    public static void main(String[] args) {
        MyBeanFactory beanFactory = new MyBeanFactory();
        beanFactory.getBean();
        System.out.println("==============");
        // 加入后处理器 灵活的扩展功能 不改变源代码
        beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Autowired"));
        beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Resource"));
        beanFactory.getBean();

    }

    // 模板方法 Template Method Pattern
    /*
        提高现有代码的 ’扩展能力‘
            1、方法的主干步骤--固定不变
            2、变化的步骤（刚开始设计不能确定）-----> 抽象为接口的抽象方法
            3、将来调用的时候传进去这些抽象方法的实现
     */
    static class MyBeanFactory {
        public Object getBean() {
            Object bean = new Object();
            System.out.println("构造" + bean);
            System.out.println("依赖注入" + bean);
            // ... 3、加入处理器，扩展依赖注入功能
            for (BeanPostProcessor processor : processors) {
                processor.inject(bean);
            }
            System.out.println("初始化" + bean);
            return bean;
        }
        // 2、加入处理器集合
        private List<BeanPostProcessor> processors = new ArrayList<>();

        // 提供加入扩展器功能
        public void addBeanPostProcessor(BeanPostProcessor processors){
            this.processors.add(processors);
        }
    }

    // 1、先设计接口
    static interface BeanPostProcessor{
        public void inject(Object bean);  //对依赖注入阶段的扩展
    }

}
